<?php

class MessageBoxModel
{
    private $messageListKeyPrefix       =   'ML/';
    private $messageContentKeyPrefix    =   'MC/';
    private $inboxType                  =   1;      #   receiveType
    private $outboxType                 =   2;      #   sendType

    public function sendMessage($info, $attachment = FALSE, $voice = FALSE)/*{{{*/
    {
        $uid       = $info['uid'];
        $mUid      = $info['mUid'];
        $nickname  = UK::getstr($info['nickname'], 24,'',1);
        $mNickname = UK::getstr($info['mNickname'], 24,'',1);
        $content   = UK::getstr($info['content'], 250);
        $msgType   = 'text';
        $dataJson  = '';
        $eventTypeGid = 0;
        // 参数判断
        if ($uid < 1 || $mUid < 1 || strlen($nickname) < 1 || strlen($mNickname) < 1 || strlen($content) < 1)
        {
            AC::$errorNo    =   'MBM001';
            return  FALSE;
        }
        
        // 附加字段 data(通知)
        if (!empty($info['msgType'])){
            $msgTypeArr = array('text', 'position', 'voice', 'image', 'event', 'articles', 'emotion', 'share');
            $msgType = strval($info['msgType']);
            if (!in_array($msgType, $msgTypeArr)){
                $msgType = 'text';
            }
        }
        
        // 附加字段
        $eventType = '';
        if (!empty($info['msgData'])){
            $dataJson = $info['msgData'];
            $dataArr = json_decode($dataJson, true);
            if (!is_array($dataArr)){
                $dataJson = '';
            }
            if (!empty($dataArr['eventType'])){
                $eventType = $dataArr['eventType'];
            }
        }
        
        // 不能给自己发私信
        if ($uid == $mUid)
        {
            AC::$errorNo    =   'MBM007';
            return  FALSE;
        }
        
        #   self -> outbox 发送人  /*{{{*/
        $outboxMessage  =   array(
                                'uid'       =>  $uid,
                                'mUid'      =>  $mUid,
                                'mNickname' =>  $mNickname,
                                'type'      =>  $this->outboxType,
                                'time'      =>  AC::SERVER_TIME,
                                'content'   =>  $content,
                                'msgType'   =>  $msgType,
                                'msgData'   =>  $dataJson
                            );
        $key    =   $this->messageContentKeyPrefix. $uid;
        $result =   Storage::addData($key, $outboxMessage);
        if (empty($result)){
            AC::$errorNo    =   'MBM004';
            return  FALSE;
        }else{
            $outboxMessage['id']    =   $result;
            $outboxMessage['status']=   0;
        }
        

        #   send -> inbox 接收人  /*{{{*/
        $inboxMessage   =   array(
                                'uid'       =>  $mUid,
                                'mUid'      =>  $uid,
                                'mNickname' =>  $nickname,
                                'type'      =>  $this->inboxType,
                                'time'      =>  AC::SERVER_TIME,
                                'content'   =>  $content,
                                'msgType'   =>  $msgType,
                                'msgData'   =>  $dataJson,
                                'mid'       =>  $outboxMessage['id']
                            );
        
        $key    =   $this->messageContentKeyPrefix. $mUid;
        $result =   Storage::addData($key, $inboxMessage);
        if (empty($result))
        {
            AC::$errorNo    =   'MBM003';
            return  FALSE;
        }
        /*}}}*/

        // 判断是否有附件
        /**
         * TODO 如有拥有附件则以发布私信的用户为KEY,将返回的私信内容中的id哈希后存入列表
         * 如果存在则去查找附件.
         */
        $key = $this->messageContentKeyPrefix. $uid;
        $message_id    =    UK::getBodyidByItemid($key, $outboxMessage['id']);
        $inboxMessage['last_attachment']    =    0;
        $outboxMessage['last_attachment']   =    0;
        if ($attachment || $voice){
            $inboxMessage['last_attachment']    =    $message_id;
            $outboxMessage['last_attachment']   =    $message_id;
        }
        $this->setMessageListInfo($inboxMessage);
        $this->setMessageListInfo($outboxMessage);
        /*}}}*/
        
        isset($info['eventTypeGid'])    &&    $eventTypeGid    =    intval($info['eventTypeGid']);
        // 发送私信的数据
        $data = array(
                'uid'      =>    $info['uid'],
                'mUid'     =>    $info['mUid'],
                'nickname' =>    $nickname,
                'mNickname'=>    $mNickname,
                'content'  =>    $content,
                'eventType'=>    $eventType,
                'eventTypeGid'    =>    $eventTypeGid
        );

        AC::$userStatistics[$mUid]['messageTimes']  =   1;
        
        // 推送
//        $push	=	new PushController();
//        $push->push($data, "pushMessage");
        
        return  array($outboxMessage);
    }/*}}}*/

    public function getMessageList($info)/*{{{*/
    {
        if (empty($info['uid']))
        {
            AC::$errorNo    =   'MBM005';
            return  FALSE;
        }
        $start  =   0;
        $length =   AC::MESSAGE_BOX_DISPLAY_LEN;
        isset($info['start'])   &&  $start  =   $info['start'];
        isset($info['length'])  &&  $length =   $info['length'];
        if ($start  <   0)  $start  =   0;

        $key    =   $this->messageListKeyPrefix. $info['uid'];
        $where  =   NULL;
        if (!empty($info['updateTime']))    $where  =   ' updateTime > '. $info['updateTime']. ' ';
        $orderBy=   ' updateTime DESC ';
        $result =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);

        return  $result;
    }/*}}}*/
    public function getMessageListUp($info)/*{{{*/
    {
        if (empty($info['uid']))
        {
            AC::$errorNo    =   'MBM005';
            return  FALSE;
        }
        if (empty($info['updateTime'])) return  $this->getMessageList($info);

        $start  =   0;
        $length =   AC::MESSAGE_BOX_DISPLAY_LEN;
        isset($info['start'])   &&  $start  =   $info['start'];
        isset($info['length'])  &&  $length =   $info['length'];
        if ($start  <   0)  $start  =   0;

        $key    =   $this->messageListKeyPrefix. $info['uid'];
        $where  =   ' updateTime > '. $info['updateTime']. ' ';
        $orderBy=   ' updateTime ASC ';
        $result =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);

        return  $result;
    }/*}}}*/
    public function getMessageListDown($info)/*{{{*/
    {
        if (empty($info['uid']))
        {
            AC::$errorNo    =   'MBM005';
            return  FALSE;
        }
        if (empty($info['updateTime'])) return  $this->getMessageList($info);

        $start  =   0;
        $length =   AC::MESSAGE_BOX_DISPLAY_LEN;
        isset($info['start'])   &&  $start  =   $info['start'];
        isset($info['length'])  &&  $length =   $info['length'];
        if ($start  <   0)  $start  =   0;

        $key    =   $this->messageListKeyPrefix. $info['uid'];
        $where  =   ' updateTime < '. $info['updateTime']. ' ';
        $orderBy=   ' updateTime DESC ';
        $result =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);

        return  $result;
    }/*}}}*/

    public function getMessageInfo($info)/*{{{*/
    {
        if (empty($info['uid']) ||  empty($info['mUid']))
        {
            AC::$errorNo    =   'MBM001';
            return  FALSE;
        }
        $start  =   0;
        $length =   AC::MESSAGE_BOX_DISPLAY_LEN;
        isset($info['start'])   &&  $start  =   $info['start'];
        isset($info['length'])  &&  $length =   $info['length'];
        if ($start  <   0)  $start  =   0;

        $key    =   $this->messageContentKeyPrefix. $info['uid'];

        $where  =   array('mUid' => $info['mUid']);
        if (!empty($info['id']))    $where  =   ' id > '. $info['id']. ' AND mUid = "'. $info['mUid']. '"';
        $orderBy=   ' id DESC ';
        $result =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);

        return  $result;
    }/*}}}*/
    public function getMessageInfoUp($info)/*{{{*/
    {
        if (empty($info['uid']) ||  empty($info['mUid']))
        {
            AC::$errorNo    =   'MBM001';
            return  FALSE;
        }
        if (empty($info['id'])) return  $this->getMessageInfo($info);

        $start  =   0;
        $length =   AC::MESSAGE_BOX_DISPLAY_LEN;
        isset($info['start'])   &&  $start  =   $info['start'];
        isset($info['length'])  &&  $length =   $info['length'];
        if ($start  <   0)  $start  =   0;

        $key    =   $this->messageContentKeyPrefix. $info['uid'];
        $where  =   ' id > '. $info['id']. ' AND mUid = "'. $info['mUid']. '"';
        $orderBy=   ' id ASC ';
        $result =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);

        return  $result;
    }/*}}}*/
    public function getMessageInfoDown($info)/*{{{*/
    {
        if (empty($info['uid']) ||  empty($info['mUid']))
        {
            AC::$errorNo    =   'MBM001';
            return  FALSE;
        }
        if (empty($info['id'])) return  $this->getMessageInfo($info);

        $start  =   0;
        $length =   AC::MESSAGE_BOX_DISPLAY_LEN;
        isset($info['start'])   &&  $start  =   $info['start'];
        isset($info['length'])  &&  $length =   $info['length'];
        if ($start  <   0)  $start  =   0;

        $key    =   $this->messageContentKeyPrefix. $info['uid'];
        $where  =   ' id < '. $info['id']. ' AND mUid = "'. $info['mUid']. '"';
        $orderBy=   ' id DESC ';
        $result =   Storage::getConditionManyData($key, $where, $orderBy, $start, $length);

        return  $result;
    }/*}}}*/

    public function getMessageInbox($info)/*{{{*/
    {
        if (empty($info['uid']))
        {
            AC::$errorNo    =   'MBM005';
            return  FALSE;
        }
        $start  =   0;
        $length =   AC::MESSAGE_BOX_DISPLAY_LEN;
        isset($info['start'])   &&  $start  =   $info['start'];
        isset($info['length'])  &&  $length =   $info['length'];
        if ($start  <   0)  $start  =   0;

        $key    =   $this->messageContentKeyPrefix. $info['uid'];
        $where  =   array('type' => $this->inboxType);
        $orderBy=   ' id DESC ';
        $result =   Storage::getConditionManyData($key, $where, $orderBy);

        return  $result;
    }/*}}}*/

    public function getMessageOutbox($info)/*{{{*/
    {
        if (empty($info['uid']))
        {
            AC::$errorNo    =   'MBM005';
            return  FALSE;
        }
        $start  =   0;
        $length =   AC::MESSAGE_BOX_DISPLAY_LEN;
        isset($info['start'])   &&  $start  =   $info['start'];
        isset($info['length'])  &&  $length =   $info['length'];
        if ($start  <   0)  $start  =   0;

        $key    =   $this->messageContentKeyPrefix. $info['uid'];
        $where  =   array('type' => $this->outboxType);
        $orderBy=   ' id DESC ';
        $result =   Storage::getConditionManyData($key, $where, $orderBy);

        return  $result;
    }/*}}}*/

    public function removeMessage($info)/*{{{*/
    {
        if (empty($info['uid']))
        {
            AC::$errorNo    =   'MBM005';
            return  FALSE;
        }
        if (empty($info['mUid']) &&  empty($info['id']))
        {
            AC::$errorNo    =   'MBM006';
            return  FALSE;
        }

        if (!empty($info['id']))
        {
            $key    =   $this->messageContentKeyPrefix. $info['uid'];
            $where  =   array('id' => $info['id']);
            $result =   Storage::delConditionData($key, $where);
        }else if (!empty($info['mUid']))
        {
            $key    =   $this->messageListKeyPrefix. $info['uid'];
            $where  =   array('mUid' => $info['mUid']);
            $result =   Storage::delConditionData($key, $where);

            $key    =   $this->messageContentKeyPrefix. $info['uid'];
            $where  =   array('mUid' => $info['mUid']);
            $result =   Storage::delConditionData($key, $where);
        }

        return  $result;
    }/*}}}*/
    // 给达人,名人发送私信
    public function sendAbilityMessage($param){
        $messageService = new MessageService;
        $result = $messageService->sendMessage($param['uid'], $param['mUid'], $param);
        //$result = $this->sendMessage($param);
        // 推送以及私信数量自增
        if (!empty($result)){
            AC::$userStatistics[$param['mUid']]['messageTimes']  =   1;
    
            // 推送
            $push	=	new PushController();
            $push->push($param, "pushMessage");
        }
    }
    
    private function setMessageListInfo($info)/*{{{*/
    {
        $uid     = intval($info['uid']);
        $mUid    = intval($info['mUid']);
        $type    = intval($info['type']);
        $content = strval($info['content']);
        if ($uid < 1 || $mUid < 1)
        {
            AC::$errorNo    =   'MBM001';
            return  FALSE;
        }
        $listInfo   =   $this->getMessageListInfo(array('uid' => $uid, 'mUid' => $mUid));

        $data = array(
                'uid'          =>   $uid,
                'mUid'         =>   $mUid,
                'time'         =>   $info['time'],
                'updateTime'   =>   AC::SERVER_TIME,
                'lastContent'  =>   $content
        );

        $where  =   array('mUid' => $mUid);
        $key    =   $this->messageListKeyPrefix. $uid;

        # insert or update messageListInfo
        if ($this->outboxType   ==  $type)/*{{{*/
        {
            $data['unReadNum']  =   0;
            if (empty($listInfo['id']))
            {
                $result =   Storage::addData($key, $data);
            }
            else
            {
                $result =   Storage::setConditionData($key, $data, $where);
            }
        }
        else
        {
            if (empty($listInfo['id']))
            {
                $data['unReadNum']  =   1;
                $result =   Storage::addData($key, $data);
            }
            else
            {
                $data['unReadNum']  =   $listInfo['unReadNum'] + 1;
                $result =   Storage::setConditionData($key, $data, $where);
            }
        }/*}}}*/

        return  $result;
    }/*}}}*/

    public function getMessageListInfo($info)/*{{{*/
    {
        if (empty($info['uid']) ||  empty($info['mUid']))
        {
            AC::$errorNo    =   'MBM001';
            return  FALSE;
        }
        $where  =   array('mUid' => $info['mUid']);
        $key    =   $this->messageListKeyPrefix. $info['uid'];
        $result =   Storage::getConditionData($key, $where);

        return  $result;
    }/*}}}*/

    public function resetUnReadNum($info)/*{{{*/
    {
        if (empty($info['uid']) ||  empty($info['mUid']))
        {
            AC::$errorNo    =   'MBM001';
            return  FALSE;
        }

        $key    =   $this->messageListKeyPrefix. $info['uid'];
        $where  =   array('mUid' => $info['mUid']);
        $value  =   array('unReadNum' => 0);

        $result =   Storage::setConditionData($key, $value, $where);
        return  $result;
    }/*}}}*/

    public function addMessage($info, $attachment = FALSE, $voice = FALSE)
    {
        $uid       = $info['uid'];
        $mUid      = $info['mUid'];
        $nickname  = UK::getstr($info['nickname'], 24,'',1);
        $mNickname = UK::getstr($info['mNickname'], 24,'',1);
        $content   = UK::getstr($info['content'], 250);
        $msgType   = $info['msgType'];
        $dataJson  = '';
        // 参数判断
        if ($uid < 1 || $mUid < 1 || strlen($nickname) < 1 || strlen($mNickname) < 1 || strlen($content) < 1)
        {
            AC::$errorNo    =   'MBM001';
            return  FALSE;
        }

        // 附加字段
        if (!empty($info['msgType'])){
            $msgTypeArr = array('text', 'position', 'voice', 'image', 'event', 'articles', 'emotion', 'share');
            $msgType = strval($info['msgType']);
            if (!in_array($msgType, $msgTypeArr)){
                $msgType = 'text';
            }
        }
        if (!empty($info['msgData'])){
            $dataJson = $info['msgData'];
            $dataArr = json_decode($dataJson, true);
            if (!is_array($dataArr)){
                $dataJson = '';
            }
        }

        #   self -> outbox 发送人  /*{{{*/
        $outboxMessage  =   array(
            'uid'       =>  $uid,
            'mUid'      =>  $mUid,
            'mNickname' =>  $mNickname,
            'type'      =>  $this->outboxType,
            'time'      =>  empty($info['time']) ? AC::SERVER_TIME : $info['time'],
            'content'   =>  $content,
            'msgType'   =>  $msgType,
            'msgData'   =>  $dataJson
        );
        $key    =   $this->messageContentKeyPrefix. $uid;
        $result =   Storage::addData($key, $outboxMessage);
        if (empty($result)){
            AC::$errorNo    =   'MBM004';
            return  FALSE;
        }else{
            $outboxMessage['id']    =   $result;
            $outboxMessage['status']=   0;
        }

        #   send -> inbox 接收人  /*{{{*/
        $inboxMessage   =   array(
            'uid'       =>  $mUid,
            'mUid'      =>  $uid,
            'mNickname' =>  $nickname,
            'type'      =>  $this->inboxType,
            'time'      =>  empty($info['time']) ? AC::SERVER_TIME : $info['time'],
            'content'   =>  $content,
            'msgType'   =>  $msgType,
            'msgData'   =>  $dataJson,
            'mid'       =>  $outboxMessage['id']
        );

        $key    =   $this->messageContentKeyPrefix. $mUid;
        $result =   Storage::addData($key, $inboxMessage);

        if (empty($result))
        {
            AC::$errorNo    =   'MBM003';
            return  FALSE;
        }

        // 判断是否有附件
        /**
         * 如果存在则去查找附件.
         */
        $key = $this->messageContentKeyPrefix. $uid;
        $message_id    =    UK::getBodyidByItemid($key, $outboxMessage['id']);
        $inboxMessage['last_attachment']    =    0;
        $outboxMessage['last_attachment']   =    0;
        if ($attachment || $voice){
            $inboxMessage['last_attachment']    =    $message_id;
            $outboxMessage['last_attachment']   =    $message_id;
        }
        $this->setMessageListInfo($inboxMessage);
        $this->setMessageListInfo($outboxMessage);

        return $outboxMessage;
    }

}


